#pragma once

#include <iostream>
#include <string>
#include <jsoncpp/json/json.h>

const std::string blank_space_sep = " ";
const std::string protocol_sep = "\n";

// #define MySelf 1

// 封装报头
// "len\nx op y\n"
std::string Encode(const std::string& content)
{
    std::string package = std::to_string(content.size());
    package += protocol_sep;
    package += content;
    package += protocol_sep;

    return package;
}

// 对收到的报文进行解包
bool Decode(std::string& package, std::string* content)
{
    int pos = package.find(protocol_sep);
    if(pos == std::string::npos) return false;
    std::string len_str = package.substr(0, pos);
    size_t len = std::stoi(len_str);
    size_t total_len = len + len_str.size() + 2;
    if(package.size() < total_len) return false;

    *content = package.substr(pos+1, len);
    package.erase(0, total_len);
    return true;
}

class Request
{
public:
    Request(int data1=0, int data2=0, char oper=0) : x(data1), y(data2), op(oper)
    {}

    // "x op y"
    bool Serialize(std::string* out)
    {
#ifdef MySelf
        std::string s = std::to_string(x);
        s += blank_space_sep;
        s += op;
        s += blank_space_sep;
        s += std::to_string(y);

        *out = s;
        return true;
#else
        Json::Value root;
        root["x"] = x;
        root["op"] = op;
        root["y"] = y;
        Json::StyledWriter writer;
        *out = writer.write(root);
        return true;
#endif
    }

    bool Deserialize(const std::string& in)
    {
#ifdef MySelf
        int left = in.find(blank_space_sep);
        if(left == std::string::npos) return false;
        std::string x_part = in.substr(0, left);

        int right = in.rfind(blank_space_sep);
        if(right - 2 != left) return false;
        std::string y_part = in.substr(right+1);

        x = std::stoi(x_part);
        y = std::stoi(y_part);
        op = in[left+1];
        return true;
#else
        Json::Value root;
        Json::Reader reader;
        reader.parse(in, root);

        x = root["x"].asInt();
        op = root["op"].asInt();
        y = root["y"].asInt();
        return true;
#endif
    }

    void DebugPrint()
    {
        std::cout << "新的请求已经构建：" << x << ' ' << op << ' ' << y  << "=?" << std::endl;
    }

    ~Request()
    {}
public:
    int x;
    int y;
    char op;
};

class Response
{
public:
    Response(int res = 0, int c = 0) : result(res), code(c)
    {}

    // "result code"
    bool Serialize(std::string* out)
    {
#ifdef MySelf

        std::string s = std::to_string(result);
        s += blank_space_sep;
        s += std::to_string(code);

        *out = s;
        return true;
#else
        Json::Value root;
        root["result"] = result;
        root["code"] = code;
        Json::StyledWriter writer;
        *out = writer.write(root);
        return true;
#endif
    }

    bool Deserialize(const std::string& in)
    {
#ifdef MySelf
        int pos = in.find(blank_space_sep);
        if(pos == std::string::npos) return false;
        
        std::string r_part = in.substr(0,pos);
        std::string c_part = in.substr(pos+1);

        result = std::stoi(r_part);
        code = std::stoi(c_part);
        return true;
#else
        Json::Value root;
        Json::Reader reader;
        reader.parse(in, root);

        result = root["result"].asInt();
        code = root["code"].asInt();
        return true;
#endif
    }

    void DebugPrint()
    {
        std::cout << "新的响应已经生成：" << result << " : " << code << std::endl;
    }

    ~Response()
    {}
public:
    int result;
    int code; // 0表示可信,其他数值表示错误原因
};